﻿using System.Collections.Generic;
using System.Windows;
using Brjnk.Common.UI;

namespace Brjnk.CoordinateSystem2D.Layers
{
    public class GraphAdapterContext
    {
        private VisualHost host = new VisualHost();

        public VisualHost Visual { get { return host; } }

        private Dictionary<object, Graph> graphs = new Dictionary<object, Graph>();

        /// <summary>
        /// Přidá novou datovou řadu. Změny předanáho objektu IList nebudou reflektovány.
        /// </summary>
        public void AddDataSerie(object key, object dataObject, IList<GraphPoint> data, GraphDataInfo dataInfo, GraphStyle style)
        {
            Graph graph;
            if (graphs.ContainsKey(key))
            {
                graph = graphs[key];
            }
            else
            {
                graph = new Graph();
                graphs.Add(key, graph);
                host.Visuals.Add(graph.Visual);
            }

            graph.SetPoints(data);
            graph.DataObject = dataObject;
            graph.DataInfo = dataInfo;
            graph.Style = style;
            graph.Recalculate(view);
            graph.RefreshView(view);
            host.InvalidateVisual();
        }

        public void ChangeStyle(object key, GraphStyle style)
        {
            if (graphs.ContainsKey(key))
            {
                var graph = graphs[key];
                graph.Style = style;
                graph.Recalculate(view);
                graph.RefreshView(view);
                host.InvalidateVisual();
            }
        }

        public void RemoveDataSerie(object key)
        {
            var graph = graphs[key];
            host.Visuals.Remove(graph.Visual);
            graphs.Remove(key);
            host.InvalidateVisual();
        }

        private ViewInfoBase view;

        /// <summary>
        /// Aktualizuje pohled (např. při zoomování)
        /// </summary>
        internal void UpdateView(ViewInfoBase view)
        {
            this.view = view;
            foreach (var g in graphs) g.Value.RefreshView(view);
            host.InvalidateVisual();
        }

        /// <summary>
        /// Přepočítá souřadnice (ViewInfoBase.Transform) a následně aktualizuje pohled.
        /// </summary>
        internal void Update(ViewInfoBase view)
        {
            this.view = view;
            foreach (var g in graphs)
            {
                g.Value.Recalculate(view);
                g.Value.RefreshView(view);
            }
            host.InvalidateVisual();
        }

        /// <summary>
        /// Vrátí ke každému grafu nejbližší grafový bod
        /// </summary>
        internal IEnumerable<GraphNearestPoint> GetNearestPoints(Point relativePosition)
        {
            foreach (var grp in graphs)
            {
                var nearestPoint = grp.Value.GetNearestPoint(relativePosition);
                if (nearestPoint != null) yield return nearestPoint;
            }
        }
    }
}